package com.derbysoft.defender.api;

import com.derbysoft.defender.api.requester.AccessTokenRequester;
import com.derbysoft.defender.api.response.OAuth2AccessToken;

import java.io.*;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>some description here.</p>
 * Created by Afee Lee on 2017-03-19 16:19
 *
 * @author Afee Lee
 * @version 1.0
 * @see Object
 * @since 1.8
 */
public class AccessTokenHolder {
    private static Map<String, OAuth2AccessToken> accessTokenMap;

    private static String file = "accessTokenHolder.dat";

    public static OAuth2AccessToken getAccessToken(String url, String clientId, String clientSecret) {
        if (accessTokenMap == null) {
            accessTokenMap = deserialize();
        }

        OAuth2AccessToken at = accessTokenMap.get(clientId);
        if (at == null || !at.getExpires().after(new Date())) {
            at = new AccessTokenRequester(clientId, clientSecret).request(url);

            if (at != null) {
                accessTokenMap.put(clientId, at);
                serialize(accessTokenMap);
            }
        }

        return at;
    }

    private static Map<String, OAuth2AccessToken> deserialize() {
        File f = new File(file);

        if (f.isFile() && f.exists()) {
            try {
                ObjectInputStream in = new ObjectInputStream(new FileInputStream(f));
                Map<String, OAuth2AccessToken> map = (Map<String, OAuth2AccessToken>) in.readObject();
                in.close();
                return map;
            } catch (IOException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }

        return new HashMap<>();
    }

    private static void serialize(Map<String, OAuth2AccessToken> accessTokenMap) {
        try {
            ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(file));
            out.writeObject(accessTokenMap);
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
